package com.nervenets.web.controller.user;

import com.nervenets.utils.JodaUtils;
import com.nervenets.web.controller.BaseController;
import com.nervenets.web.entity.KeyValue;
import com.nervenets.web.entity.MessageCode;
import com.nervenets.web.hibernate.dao.FeedbackDao;
import com.nervenets.web.hibernate.domain.Feedback;
import com.nervenets.web.redis.GlobalService;
import com.nervenets.web.redis.GlobalVariablesService;
import com.nervenets.web.redis.domain.user.UserStored;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.persistence.criteria.Predicate;
import javax.validation.ConstraintViolation;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

@Api(value = "投诉建议接口v1", description = "投诉建议接口")
@RestController
@RequestMapping("/api/v1/feedback")
public class FeedbackController extends BaseController {
    @Resource
    private FeedbackDao feedbackDao;

    @ApiOperation("投诉建议列表")
    @PostMapping("/list")
    public String list(@RequestBody FeedbackListPagingParams params) {
        final Set<ConstraintViolation<FeedbackListPagingParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        Specification<Feedback> specification = (Specification<Feedback>) (root, criteriaQuery, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (0 != params.getTargetUserId()) {
                predicates.add(criteriaBuilder.equal(root.get("userId"), params.getTargetUserId()));
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        };
        final Page<Feedback> page = feedbackDao.findAll(specification, PageRequest.of(params.getPage(), params.getLimit(), new Sort(Sort.Direction.DESC, "id")));
        HashMap<Long, UserStored> userStoredHashMap = new HashMap<>();
        List<Feedback> list = new ArrayList<>();
        page.map(feedback -> {
            list.add(feedback);
            if (!userStoredHashMap.containsKey(feedback.getUserId()) && feedback.getUserId() > 0) {
                userStoredHashMap.put(feedback.getUserId(), globalService.getUser(feedback.getUserId()));
            }
            return feedback;
        });

        return successMessage(list
                , new KeyValue("page", params.getPage())
                , new KeyValue("total", page.getTotalElements())
                , new KeyValue("users", userStoredHashMap)
        );
    }

    @ApiOperation("投诉建议提交")
    @PostMapping("/submit")
    public String submit(@RequestBody FeedbackSubmitParams params) {
        final Set<ConstraintViolation<FeedbackSubmitParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        if (0 == params.resolveUserId()) return errorMessage(MessageCode.code_777);
        final UserStored user = globalService.getUser(params.resolveUserId());
        if (null == user) return errorMessage(MessageCode.code_777);

        if (!globalVariablesService.canProceedCustom("user-feedback-" + user.getUserId(), 300)) {
            return errorMessage(MessageCode.code_444, "在五分钟内，为了防止重复提交，每个用户只能提交一次投诉建议，请想好后再提交！");
        }

        Feedback feedback = new Feedback(user.getUserId(), params.getContent(), params.getPictures(), null, 0);
        feedbackDao.save(feedback);

        return successMessage();
    }

    @ApiOperation("投诉建议回复或标记处理")
    @PostMapping("/reply")
    public String reply(@RequestBody FeedbackReplyParams params) {
        final Set<ConstraintViolation<FeedbackReplyParams>> errors = validator.validate(params);
        if (!errors.isEmpty()) {
            return errorMessage(errors);
        }

        if (0 == params.resolveUserId()) return errorMessage(MessageCode.code_777);

        final Feedback feedback = feedbackDao.findById(params.getFeedbackId()).orElse(null);
        if (null == feedback) return errorMessage(MessageCode.code_404, "您要处理的反馈不存在");
        feedback.setReply(params.getReply());
        feedback.setReplyTime(JodaUtils.getTimestamp());
        feedbackDao.save(feedback);

        return successMessage();
    }
}
